package roborally.model.executables;

import java.util.List;

/**
 * A class implementing the interface Executable, representing a sequence of executables. 
 */
public class Sequence extends Executable {
	private final List<Executable> commands;
	/**
	 * Constructs a sequence of Executables. A list of Executable objects must be given as parameter.
	 */
	public Sequence(List<Executable> commands){
		this.commands = commands;
	}
	
	@Override
	public boolean executeNextRobotCommand(RobotCommand lastExecutedRobotCommand){
		if( lastExecutedRobotCommand == null || (!this.contains(lastExecutedRobotCommand)) ){
			for(Executable executable : commands){
				if(executable.executeNextRobotCommand(null)) return true;
			}
			return false;
		}
		else{
			Executable exec = getExecutableContaining(lastExecutedRobotCommand); //get the executable that contains the lastExecutedRobotCommand
			if(exec.executeNextRobotCommand(lastExecutedRobotCommand)) return true;
			//if next robotcommand was not executed in 'executable', continue with the next executable in the sequence.
			boolean flag = false;
			for(Executable executable : commands){
				if(flag){
					if(executable.executeNextRobotCommand(null)) 
						return true;
				}
				if(executable == exec) flag = true;
			}
			return false;
		}
	}

	@Override
	public boolean contains(Executable other) {
		return getExecutableContaining(other) != null;
	}
	
	/**
	 * @return Returns the Executable in the sequence that contains the Executable 'other' given as parameter.
	 * 			If none of the Executables in the sequence contain this Executable, null is returned.
	 */
	private Executable getExecutableContaining(Executable other){
		for(Executable executable : commands){
			if(executable.contains(other)) return executable;
		}
		return null;
	}
	
}
